package com.tools.common.object;

import com.tools.common.container.MapEnum;
import com.tools.common.container.OwnPairs;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentSkipListMap;

/**
 * Map 等键值对容器操作类的
 * 一些通用方法的封装抽取
 * */
@Note("Map 等键值对容器操作类的一些通用方法的封装抽取")
class MapKit extends ReflexKit {

    MapKit() {}

    /* *******************************************************************************************
     *
     *          HashMap
     *
     * *******************************************************************************************
     * */

    public static <K, V> HashMap<K, V> toHashMap(Map source, C<K> keyType, C<V> valueType) {
        return toHashMap(source, keyType, valueType, null);
    }

    public static <K, V> HashMap<K, V> toHashMap(Map source, C<K> keyType, C<V> valueType, ForcePair force) {
        if(source == null || source.isEmpty()) return new HashMap<>();
        return (HashMap<K, V>) private_asMap(new HashMap<>(MapEnum.calcInitSize(source.size())), source, keyType, valueType, force);
    }

    public static <K, V> HashMap<K, V> toHashMap(Map<? extends K, ? extends V> source) {
        return toHashMap(source, (ForcePair<K, V>) null);
    }

    public static <K, V> HashMap<K, V> toHashMap(Map<? extends K, ? extends V> source, ForcePair<K, V> force) {
        if(source == null || source.isEmpty()) return new HashMap<>();
        return (HashMap<K, V>) private_asMap(new HashMap<>(MapEnum.calcInitSize(source.size())), source, force);
    }

    public static <K, V> HashMap<K, V> toHashMap(OwnPairs source, C<K> keyType, C<V> valueType) {
        return toHashMap(source, keyType, valueType, null);
    }

    public static <K, V> HashMap<K, V> toHashMap(OwnPairs source, C<K> keyType, C<V> valueType, ForcePair force) {
        if(source == null || source.isEmpty()) return new HashMap<>();
        return (HashMap<K, V>) private_asMap(new HashMap<>(MapEnum.calcInitSize(source.size())), source, keyType, valueType, force);
    }

    public static <K, V> HashMap<K, V> toHashMap(OwnPairs<? extends K, ? extends V> source) {
        return toHashMap(source, (ForcePair<K, V>) null);
    }

    public static <K, V> HashMap<K, V> toHashMap(OwnPairs<? extends K, ? extends V> source, ForcePair<K, V> force) {
        if(source == null || source.isEmpty()) return new HashMap<>();
        return (HashMap<K, V>) private_asMap(new HashMap<>(MapEnum.calcInitSize(source.size())), source, force);
    }

    public static HashMap<String, String> propertiesToHashMap(Properties properties) {
        return propertiesToHashMap(properties, null);
    }

    public static HashMap<String, String> propertiesToHashMap(Properties properties, ForcePair<String, String> force) {
        if(properties == null || properties.isEmpty()) return new HashMap<>();
        return (HashMap<String, String>) private_propertiesAsMap(new HashMap<>(MapEnum.calcInitSize(properties.size())), properties, force);
    }


    public static <T>HashMap<String, Object> toHashMap(T javaBean) {
        return toHashMap(javaBean, null);
    }

    public static <T>HashMap<String, Object> toHashMap(T javaBean, ForcePair<String, Object> force) {
        if(javaBean == null) return new HashMap<>();
        HashMap<String, Object> result = new HashMap<>();
        addAllFieldValue(result, javaBean, force);
        return result;
    }

    public static HashMap<String, Object> toHashMap(Properties properties) {
        if(properties == null || properties.isEmpty()) return new HashMap<>();
        return (HashMap<String, Object>) private_propertiesAsMap2(new HashMap<>(MapEnum.calcInitSize(properties.size())), properties, null);
    }

    public static HashMap<String, Object> toHashMap(Properties properties, ForcePair<String, String> force) {
        if(properties == null || properties.isEmpty()) return new HashMap<>();
        return (HashMap<String, Object>) private_propertiesAsMap2(new HashMap<>(MapEnum.calcInitSize(properties.size())), properties, force);
    }


    /* *******************************************************************************************
     *
     *          LinkedHashMap
     *
     * *******************************************************************************************
     * */


    public static <K, V> LinkedHashMap<K, V> toLinkedHashMap(Map source, C<K> keyType, C<V> valueType) {
        return toLinkedHashMap(source, keyType, valueType, null);
    }


    public static <K, V> LinkedHashMap<K, V> toLinkedHashMap(Map source, C<K> keyType, C<V> valueType, ForcePair force) {
        if(source == null || source.isEmpty()) return new LinkedHashMap<>();
        return (LinkedHashMap<K, V>) private_asMap(new LinkedHashMap<>(MapEnum.calcInitSize(source.size())), source, keyType, valueType, force);
    }

    public static <K, V> LinkedHashMap<K, V> toLinkedHashMap(Map<? extends K, ? extends V> source) {
        return toLinkedHashMap(source, (ForcePair<K, V>) null);
    }

    public static <K, V> LinkedHashMap<K, V> toLinkedHashMap(Map<? extends K, ? extends V> source, ForcePair<K, V> force) {
        if(source == null || source.isEmpty()) return new LinkedHashMap<>();
        return (LinkedHashMap<K, V>) private_asMap(new LinkedHashMap<>(MapEnum.calcInitSize(source.size())), source, force);
    }

    public static <K, V> LinkedHashMap<K, V> toLinkedHashMap(OwnPairs source, C<K> keyType, C<V> valueType) {
        return toLinkedHashMap(source, keyType, valueType, null);
    }

    public static <K, V> LinkedHashMap<K, V> toLinkedHashMap(OwnPairs source, C<K> keyType, C<V> valueType, ForcePair force) {
        if(source == null || source.isEmpty()) return new LinkedHashMap<>();
        return (LinkedHashMap<K, V>) private_asMap(new LinkedHashMap<>(MapEnum.calcInitSize(source.size())), source, keyType, valueType, force);
    }

    public static <K, V> LinkedHashMap<K, V> toLinkedHashMap(OwnPairs<? extends K, ? extends V> source) {
        return toLinkedHashMap(source, (ForcePair<K, V>) null);
    }

    public static <K, V> LinkedHashMap<K, V> toLinkedHashMap(OwnPairs<? extends K, ? extends V> source, ForcePair<K, V> force) {
        if(source == null || source.isEmpty()) return new LinkedHashMap<>();
        return (LinkedHashMap<K, V>) private_asMap(new LinkedHashMap<>(MapEnum.calcInitSize(source.size())), source, force);
    }

    public static LinkedHashMap<String, String> propertiesToLinkedHashMap(Properties properties) {
        return propertiesToLinkedHashMap(properties, null);
    }

    public static LinkedHashMap<String, String> propertiesToLinkedHashMap(Properties properties, ForcePair<String, String> force) {
        if(properties == null || properties.isEmpty()) return new LinkedHashMap<>();
        return (LinkedHashMap<String, String>) private_propertiesAsMap(new LinkedHashMap<>(MapEnum.calcInitSize(properties.size())), properties, force);
    }

    public static <T>LinkedHashMap<String, Object> toLinkedHashMap(T javaBean) {
        return toLinkedHashMap(javaBean, null);
    }

    public static <T>LinkedHashMap<String, Object> toLinkedHashMap(T javaBean, ForcePair<String, Object> force) {
        if(javaBean == null) return new LinkedHashMap<>();
        LinkedHashMap<String, Object> result = new LinkedHashMap<>();
        addAllFieldValue(result, javaBean, force);
        return result;
    }

    public static LinkedHashMap<String, Object> toLinkedHashMap(Properties properties) {
        if(properties == null || properties.isEmpty()) return new LinkedHashMap<>();
        return (LinkedHashMap<String, Object>) private_propertiesAsMap2(new LinkedHashMap<>(MapEnum.calcInitSize(properties.size())), properties, null);
    }

    public static LinkedHashMap<String, Object> toLinkedHashMap(Properties properties, ForcePair<String, String> force) {
        if(properties == null || properties.isEmpty()) return new LinkedHashMap<>();
        return (LinkedHashMap<String, Object>) private_propertiesAsMap2(new LinkedHashMap<>(MapEnum.calcInitSize(properties.size())), properties, force);
    }

    /* *******************************************************************************************
     *
     *          ConcurrentHashMap
     *
     * *******************************************************************************************
     * */

    public static <K, V> ConcurrentHashMap<K, V> toConcurrentHashMap(Map source, C<K> keyType, C<V> valueType) {
        return toConcurrentHashMap(source, keyType, valueType, null);
    }


    public static <K, V> ConcurrentHashMap<K, V> toConcurrentHashMap(Map source, C<K> keyType, C<V> valueType, ForcePair force) {
        if(source == null || source.isEmpty()) return new ConcurrentHashMap<>();
        return (ConcurrentHashMap<K, V>) private_asMap(new ConcurrentHashMap<>(MapEnum.calcInitSize(source.size())), source, keyType, valueType, force);
    }

    public static <K, V> ConcurrentHashMap<K, V> toConcurrentHashMap(Map<? extends K, ? extends V> source) {
        return toConcurrentHashMap(source, (ForcePair<K, V>) null);
    }

    public static <K, V> ConcurrentHashMap<K, V> toConcurrentHashMap(Map<? extends K, ? extends V> source, ForcePair<K, V> force) {
        if(source == null) return new ConcurrentHashMap<>();
        return (ConcurrentHashMap<K, V>) private_asMap(new ConcurrentHashMap<>(MapEnum.calcInitSize(source.size())), source, force);
    }

    public static <K, V> ConcurrentHashMap<K, V> toConcurrentHashMap(OwnPairs source, C<K> keyType, C<V> valueType) {
        return toConcurrentHashMap(source, keyType, valueType, null);
    }

    public static <K, V> ConcurrentHashMap<K, V> toConcurrentHashMap(OwnPairs source, C<K> keyType, C<V> valueType, ForcePair force) {
        if(source == null || source.isEmpty()) return new ConcurrentHashMap<>();
        return (ConcurrentHashMap<K, V>) private_asMap(new ConcurrentHashMap<>(MapEnum.calcInitSize(source.size())), source, keyType, valueType, force);
    }

    public static <K, V> ConcurrentHashMap<K, V> toConcurrentHashMap(OwnPairs<? extends K, ? extends V> source) {
        return toConcurrentHashMap(source, (ForcePair<K, V>) null);
    }

    public static <K, V> ConcurrentHashMap<K, V> toConcurrentHashMap(OwnPairs<? extends K, ? extends V> source, ForcePair<K, V> force) {
        if(source == null || source.isEmpty()) return new ConcurrentHashMap<>();
        return (ConcurrentHashMap<K, V>) private_asMap(new ConcurrentHashMap<>(MapEnum.calcInitSize(source.size())), source, force);
    }

    public static ConcurrentHashMap<String, String> propertiesToConcurrentHashMap(Properties properties) {
        return propertiesToConcurrentHashMap(properties, null);
    }

    public static ConcurrentHashMap<String, String> propertiesToConcurrentHashMap(Properties properties, ForcePair<String, String> force) {
        if(properties == null || properties.isEmpty()) return new ConcurrentHashMap<>();
        return (ConcurrentHashMap<String, String>) private_propertiesAsMap(new ConcurrentHashMap<>(MapEnum.calcInitSize(properties.size())), properties, force);
    }

    public static <T>ConcurrentHashMap<String, Object> toConcurrentHashMap(T javaBean) {
        return toConcurrentHashMap(javaBean, null);
    }

    public static <T>ConcurrentHashMap<String, Object> toConcurrentHashMap(T javaBean, ForcePair<String, Object> force) {
        if(javaBean == null) return new ConcurrentHashMap<>();
        ConcurrentHashMap<String, Object> result = new ConcurrentHashMap<>();
        addAllFieldValue(result, javaBean, force);
        return result;
    }

    public static ConcurrentHashMap<String, Object> toConcurrentHashMap(Properties properties) {
        if(properties == null || properties.isEmpty()) return new ConcurrentHashMap<>();
        return (ConcurrentHashMap<String, Object>) private_propertiesAsMap2(new ConcurrentHashMap<>(MapEnum.calcInitSize(properties.size())), properties, null);
    }

    public static ConcurrentHashMap<String, Object> toConcurrentHashMap(Properties properties, ForcePair<String, String> force) {
        if(properties == null || properties.isEmpty()) return new ConcurrentHashMap<>();
        return (ConcurrentHashMap<String, Object>) private_propertiesAsMap2(new ConcurrentHashMap<>(MapEnum.calcInitSize(properties.size())), properties, force);
    }

    /* *******************************************************************************************
     *
     *          TreeMap
     *
     * *******************************************************************************************
     * */

    public static <K, V> TreeMap<K, V> toTreeMap(Map source, C<K> keyType, C<V> valueType) {
        return toTreeMap(source, keyType, valueType, null, null);
    }

    public static <K, V> TreeMap<K, V> toTreeMap(Map source, C<K> keyType, C<V> valueType, ForcePair force) {
        return toTreeMap(source, keyType, valueType, null, force);
    }

    public static <K, V> TreeMap<K, V> toTreeMap(Map source, C<K> keyType, C<V> valueType, Comparator<? super K> c) {
        return toTreeMap(source, keyType, valueType, c, null);
    }

    public static <K, V> TreeMap<K, V> toTreeMap(Map source, C<K> keyType, C<V> valueType, Comparator<? super K> c, ForcePair force) {
        if(source == null || source.isEmpty()) return new TreeMap<>(c);
        return (TreeMap<K, V>) private_asMap(new TreeMap<>(c), source, keyType, valueType, force);
    }

    public static <K, V> TreeMap<K, V> toTreeMap(Map<? extends K, ? extends V> source) {
        return toTreeMap(source, (Comparator<? super K>) null, null);
    }

    public static <K, V> TreeMap<K, V> toTreeMap(Map<? extends K, ? extends V> source, Comparator<? super K> c) {
        return toTreeMap(source, c, null);
    }

    public static <K, V> TreeMap<K, V> toTreeMap(Map<? extends K, ? extends V> source, ForcePair<K, V> force) {
        return toTreeMap(source, null, force);
    }

    public static <K, V> TreeMap<K, V> toTreeMap(Map<? extends K, ? extends V> source, Comparator<? super K> c, ForcePair<K, V> force) {
        if(source == null || source.isEmpty()) return new TreeMap<>(c);
        return (TreeMap<K, V>) private_asMap(new TreeMap<>(c), source, force);
    }

    public static <K, V> TreeMap<K, V> toTreeMap(OwnPairs source, C<K> keyType, C<V> valueType) {
        return toTreeMap(source, keyType, valueType, null, null);
    }

    public static <K, V> TreeMap<K, V> toTreeMap(OwnPairs source, C<K> keyType, C<V> valueType, ForcePair force) {
        return toTreeMap(source, keyType, valueType, null, force);
    }

    public static <K, V> TreeMap<K, V> toTreeMap(OwnPairs source, C<K> keyType, C<V> valueType, Comparator<? super K> c) {
        return toTreeMap(source, keyType, valueType, c, null);
    }

    public static <K, V> TreeMap<K, V> toTreeMap(OwnPairs source, C<K> keyType, C<V> valueType, Comparator<? super K> c, ForcePair force) {
        if(source == null || source.isEmpty()) return new TreeMap<>(c);
        return (TreeMap<K, V>) private_asMap(new TreeMap<>(c), source, keyType, valueType, force);
    }

    public static <K, V> TreeMap<K, V> toTreeMap(OwnPairs<? extends K, ? extends V> source) {
        return toTreeMap(source, (Comparator<? super K>) null, null);
    }

    public static <K, V> TreeMap<K, V> toTreeMap(OwnPairs<? extends K, ? extends V> source, Comparator<? super K> c) {
        return toTreeMap(source, c, null);
    }

    public static <K, V> TreeMap<K, V> toTreeMap(OwnPairs<? extends K, ? extends V> source, ForcePair<K, V> force) {
        return toTreeMap(source, null, force);
    }

    public static <K, V> TreeMap<K, V> toTreeMap(OwnPairs<? extends K, ? extends V> source, Comparator<? super K> c, ForcePair<K, V> force) {
        if(source == null || source.isEmpty()) return new TreeMap<>(c);
        return (TreeMap<K, V>) private_asMap(new TreeMap<>(c), source, force);
    }

    public static TreeMap<String, String> propertiesToTreeMap(Properties properties) {
        return propertiesToTreeMap(properties, null, null);
    }

    public static TreeMap<String, String> propertiesToTreeMap(Properties properties, ForcePair<String, String> force) {
        return propertiesToTreeMap(properties, null, force);
    }

    public static TreeMap<String, String> propertiesToTreeMap(Properties properties, Comparator<String> c) {
        return propertiesToTreeMap(properties, c, null);
    }

    public static TreeMap<String, String> propertiesToTreeMap(Properties properties, Comparator<String> c, ForcePair<String, String> force) {
        if(properties == null || properties.isEmpty()) return new TreeMap<>(c);
        return (TreeMap<String, String>) private_propertiesAsMap(new TreeMap<>(c), properties, force);
    }

    public static <T>TreeMap<String, Object> toTreeMap(T javaBean) {
        return toTreeMap(javaBean, null, null);
    }

    public static <T>TreeMap<String, Object> toTreeMap(T javaBean, Comparator<String> c) {
        return toTreeMap(javaBean, c, null);
    }

    public static <T>TreeMap<String, Object> toTreeMap(T javaBean, ForcePair<String, Object> force) {
        return toTreeMap(javaBean, null, force);
    }

    public static <T>TreeMap<String, Object> toTreeMap(T javaBean, Comparator<String> c, ForcePair<String, Object> force) {
        if(javaBean == null) return new TreeMap<>(c);
        TreeMap<String, Object> result = new TreeMap<>(c);
        addAllFieldValue(result, javaBean, force);
        return result;
    }

    public static TreeMap<String, Object> toTreeMap(Properties properties) {
        if(properties == null || properties.isEmpty()) return new TreeMap<>();
        return (TreeMap<String, Object>) private_propertiesAsMap2(new TreeMap<>(), properties, null);
    }

    public static TreeMap<String, Object> toTreeMap(Properties properties, ForcePair<String, String> force) {
        if(properties == null || properties.isEmpty()) return new TreeMap<>();
        return (TreeMap<String, Object>) private_propertiesAsMap2(new TreeMap<>(), properties, force);
    }

    public static TreeMap<String, Object> toTreeMap(Properties properties, Comparator<String> c) {
        if(properties == null || properties.isEmpty()) return new TreeMap<>(c);
        return (TreeMap<String, Object>) private_propertiesAsMap2(new TreeMap<>(c), properties, null);
    }

    public static TreeMap<String, Object> toTreeMap(Properties properties, Comparator<String> c, ForcePair<String, String> force) {
        if(properties == null || properties.isEmpty()) return new TreeMap<>(c);
        return (TreeMap<String, Object>) private_propertiesAsMap2(new TreeMap<>(c), properties, force);
    }


    /* *******************************************************************************************
     *
     *          TreeMap
     *
     * *******************************************************************************************
     * */

    public static <K, V> ConcurrentSkipListMap<K, V> toConcurrentSkipListMap(Map source, C<K> keyType, C<V> valueType) {
        return toConcurrentSkipListMap(source, keyType, valueType, null, null);
    }

    public static <K, V> ConcurrentSkipListMap<K, V> toConcurrentSkipListMap(Map source, C<K> keyType, C<V> valueType, ForcePair force) {
        return toConcurrentSkipListMap(source, keyType, valueType, null, force);
    }

    public static <K, V> ConcurrentSkipListMap<K, V> toConcurrentSkipListMap(Map source, C<K> keyType, C<V> valueType, Comparator<? super K> c) {
        return toConcurrentSkipListMap(source, keyType, valueType, c, null);
    }

    public static <K, V> ConcurrentSkipListMap<K, V> toConcurrentSkipListMap(Map source, C<K> keyType, C<V> valueType, Comparator<? super K> c, ForcePair force) {
        if(source == null || source.isEmpty()) return new ConcurrentSkipListMap<>(c);
        return (ConcurrentSkipListMap<K, V>) private_asMap(new ConcurrentSkipListMap<>(c), source, keyType, valueType, force);
    }

    public static <K, V> ConcurrentSkipListMap<K, V> toConcurrentSkipListMap(Map<? extends K, ? extends V> source) {
        return toConcurrentSkipListMap(source, (Comparator<? super K>) null, null);
    }

    public static <K, V> ConcurrentSkipListMap<K, V> toConcurrentSkipListMap(Map<? extends K, ? extends V> source, Comparator<? super K> c) {
        return toConcurrentSkipListMap(source, c, null);
    }

    public static <K, V> ConcurrentSkipListMap<K, V> toConcurrentSkipListMap(Map<? extends K, ? extends V> source, ForcePair<K, V> force) {
        return toConcurrentSkipListMap(source, null, force);
    }

    public static <K, V> ConcurrentSkipListMap<K, V> toConcurrentSkipListMap(Map<? extends K, ? extends V> source, Comparator<? super K> c, ForcePair<K, V> force) {
        if(source == null || source.isEmpty()) return new ConcurrentSkipListMap<>(c);
        return (ConcurrentSkipListMap<K, V>) private_asMap(new ConcurrentSkipListMap<>(c), source, force);
    }

    public static <K, V> ConcurrentSkipListMap<K, V> toConcurrentSkipListMap(OwnPairs source, C<K> keyType, C<V> valueType) {
        return toConcurrentSkipListMap(source, keyType, valueType, null, null);
    }

    public static <K, V> ConcurrentSkipListMap<K, V> toConcurrentSkipListMap(OwnPairs source, C<K> keyType, C<V> valueType, ForcePair force) {
        return toConcurrentSkipListMap(source, keyType, valueType, null, force);
    }

    public static <K, V> ConcurrentSkipListMap<K, V> toConcurrentSkipListMap(OwnPairs source, C<K> keyType, C<V> valueType, Comparator<? super K> c) {
        return toConcurrentSkipListMap(source, keyType, valueType, c, null);
    }

    public static <K, V> ConcurrentSkipListMap<K, V> toConcurrentSkipListMap(OwnPairs source, C<K> keyType, C<V> valueType, Comparator<? super K> c, ForcePair force) {
        if(source == null || source.isEmpty()) return new ConcurrentSkipListMap<>(c);
        return (ConcurrentSkipListMap<K, V>) private_asMap(new ConcurrentSkipListMap<>(c), source, keyType, valueType, force);
    }

    public static <K, V> ConcurrentSkipListMap<K, V> toConcurrentSkipListMap(OwnPairs<? extends K, ? extends V> source) {
        return toConcurrentSkipListMap(source, (Comparator<? super K>) null, null);
    }

    public static <K, V> ConcurrentSkipListMap<K, V> toConcurrentSkipListMap(OwnPairs<? extends K, ? extends V> source, Comparator<? super K> c) {
        return toConcurrentSkipListMap(source, c, null);
    }

    public static <K, V> ConcurrentSkipListMap<K, V> toConcurrentSkipListMap(OwnPairs<? extends K, ? extends V> source, ForcePair<K, V> force) {
        return toConcurrentSkipListMap(source, null, force);
    }

    public static <K, V> ConcurrentSkipListMap<K, V> toConcurrentSkipListMap(OwnPairs<? extends K, ? extends V> source, Comparator<? super K> c, ForcePair<K, V> force) {
        if(source == null || source.isEmpty()) return new ConcurrentSkipListMap<>(c);
        return (ConcurrentSkipListMap<K, V>) private_asMap(new ConcurrentSkipListMap<>(c), source, force);
    }

    public static ConcurrentSkipListMap<String, String> propertiesToConcurrentSkipListMap(Properties properties) {
        return propertiesToConcurrentSkipListMap(properties, null, null);
    }

    public static ConcurrentSkipListMap<String, String> propertiesToConcurrentSkipListMap(Properties properties, ForcePair<String, String> force) {
        return propertiesToConcurrentSkipListMap(properties, null, force);
    }

    public static ConcurrentSkipListMap<String, String> propertiesToConcurrentSkipListMap(Properties properties, Comparator<String> c) {
        return propertiesToConcurrentSkipListMap(properties, c, null);
    }

    public static ConcurrentSkipListMap<String, String> propertiesToConcurrentSkipListMap(Properties properties, Comparator<String> c, ForcePair<String, String> force) {
        if(properties == null || properties.isEmpty()) return new ConcurrentSkipListMap<>(c);
        return (ConcurrentSkipListMap<String, String>) private_propertiesAsMap(new ConcurrentSkipListMap<>(c), properties, force);
    }


    public static <T>ConcurrentSkipListMap<String, Object> toConcurrentSkipListMap(T javaBean) {
        return toConcurrentSkipListMap(javaBean, null, null);
    }

    public static <T>ConcurrentSkipListMap<String, Object> toConcurrentSkipListMap(T javaBean, Comparator<String> c) {
        return toConcurrentSkipListMap(javaBean, c, null);
    }

    public static <T>ConcurrentSkipListMap<String, Object> toConcurrentSkipListMap(T javaBean, ForcePair<String, Object> force) {
        return toConcurrentSkipListMap(javaBean, null, force);
    }

    public static <T>ConcurrentSkipListMap<String, Object> toConcurrentSkipListMap(T javaBean, Comparator<String> c, ForcePair<String, Object> force) {
        if(javaBean == null) return new ConcurrentSkipListMap<>(c);
        ConcurrentSkipListMap<String, Object> result = new ConcurrentSkipListMap<>(c);
        addAllFieldValue(result, javaBean, force);
        return result;
    }


    public static ConcurrentSkipListMap<String, Object> toConcurrentSkipListMap(Properties properties) {
        if(properties == null || properties.isEmpty()) return new ConcurrentSkipListMap<>();
        return (ConcurrentSkipListMap<String, Object>) private_propertiesAsMap2(new ConcurrentSkipListMap<>(), properties, null);
    }


    public static ConcurrentSkipListMap<String, Object> toConcurrentSkipListMap(Properties properties, ForcePair<String, String> force) {
        if(properties == null || properties.isEmpty()) return new ConcurrentSkipListMap<>();
        return (ConcurrentSkipListMap<String, Object>) private_propertiesAsMap2(new ConcurrentSkipListMap<>(), properties, force);
    }


    public static ConcurrentSkipListMap<String, Object> toConcurrentSkipListMap(Properties properties, Comparator<String> c) {
        if(properties == null || properties.isEmpty()) return new ConcurrentSkipListMap<>(c);
        return (ConcurrentSkipListMap<String, Object>) private_propertiesAsMap2(new ConcurrentSkipListMap<>(c), properties, null);
    }


    public static ConcurrentSkipListMap<String, Object> toConcurrentSkipListMap(Properties properties, Comparator<String> c, ForcePair<String, String> force) {
        if(properties == null || properties.isEmpty()) return new ConcurrentSkipListMap<>(c);
        return (ConcurrentSkipListMap<String, Object>) private_propertiesAsMap2(new ConcurrentSkipListMap<>(c), properties, force);
    }

    /* *******************************************************************************************
     *
     *          拷贝 -> Map
     *
     * *******************************************************************************************
     * */

    public static <K, V>void copy(Map source, Map<K, V> target, C<K> keyType, C<V> valueType) {
        if(source == null || source.isEmpty() || target == null) return;
        private_asMap(target, source, keyType, valueType, null);
    }

    public static <K, V>void copy(Map source, Map<K, V> target, C<K> keyType, C<V> valueType, ForcePair force) {
        if(source == null || source.isEmpty() || target == null) return;
        private_asMap(target, source, keyType, valueType, force);
    }

    public static <K, V>void copy(Map<? extends K, ? extends V> source, Map<K, V> target) {
        copy(source, target, null);
    }

    public static <K, V>void copy(Map<? extends K, ? extends V> source, Map<K, V> target, ForcePair<K, V> force) {
        if(source == null || source.isEmpty() || target == null) return;
        private_asMap(target, source, force);
    }

    public static <K, V>void copy(OwnPairs source, Map<K, V> target, C<K> keyType, C<V> valueType) {
        if(source == null || source.isEmpty() || target == null) return;
        private_asMap(target, source, keyType, valueType, null);
    }

    public static <K, V>void copy(OwnPairs source, Map<K, V> target, C<K> keyType, C<V> valueType, ForcePair force) {
        if(source == null || source.isEmpty() || target == null) return;
        private_asMap(target, source, keyType, valueType, force);
    }

    public static <K, V>void copy(OwnPairs<? extends K, ? extends V> source, Map<K, V> target) {
        copy(source, target, null);
    }

    public static <K, V>void copy(OwnPairs<? extends K, ? extends V> source, Map<K, V> target, ForcePair<K, V> force) {
        if(source == null || source.isEmpty() || target == null) return;
        private_asMap(target, source, force);
    }

    public static <K, V>void copy(Properties source, Map<K, V> target, C<K> keyType, C<V> valueType) {
        if(source == null || source.isEmpty() || target == null) return;
        private_asMap(target, source, keyType, valueType, null);
    }

    public static <K, V>void copy(Properties source, Map<K, V> target, C<K> keyType, C<V> valueType, ForcePair<String, String> force) {
        if(source == null || source.isEmpty() || target == null) return;
        private_asMap(target, source, keyType, valueType, force);
    }

    public static <K, V>void copy(Object sourceJavaBean, Map<K, V> target, C<K> keyType, C<V> valueType) {
        copy(sourceJavaBean, target, keyType, valueType, null);
    }

    public static <K, V>void copy(Object sourceJavaBean, Map<K, V> target, C<K> keyType, C<V> valueType, ForcePair<String, Object> force) {
        if(sourceJavaBean == null || target == null) return;
        Map<String, Object> fieldValueMap = allFieldValue(sourceJavaBean);
        if(force == null) {
            for (Map.Entry<String, Object> e : fieldValueMap.entrySet()) {
                target.put((K) ObjKit.toRealValue(e.getKey(), keyType), (V) ObjKit.toRealValue(e.getValue(), valueType));
            }
            return;
        }
        for (Map.Entry<String, Object> e : fieldValueMap.entrySet()) {
            e = force.force(e.getKey(), e.getValue());
            if(e != null) target.put((K) ObjKit.toRealValue(e.getKey(), keyType), (V) ObjKit.toRealValue(e.getValue(), valueType));
        }
    }

    public static void propertiesCopy(Properties source, Map<String, String> target) {
        propertiesCopy(source, target, null);
    }

    public static void propertiesCopy(Properties source, Map<String, String> target, ForcePair<String, String> force) {
        if(source == null || source.isEmpty() || target == null) return;
        private_propertiesAsMap(target, source, force);
    }

    public static void copy(Properties source, Map<String, Object> target) {
        copy(source, target, null);
    }

    public static void copy(Properties source, Map<String, Object> target, ForcePair<String, String> force) {
        if(source == null || source.isEmpty() || target == null) return;
        private_propertiesAsMap2(target, source, force);
    }

    /* *******************************************************************************************
     *
     *          私有逻辑
     *
     * *******************************************************************************************
     * */

    @Note("将 source 里的数据拷贝到 result 里，拷贝过程中会对 key、value 做指定的类型转换")
    private static <K, V> Map<K, V> private_asMap(Map<K, V> result, Map source, C<K> keyType, C<V> valueType, ForcePair force) {
        if(force == null) {
            for (Object o : source.entrySet()) {
                Map.Entry e = (Map.Entry) o;
                K key = (K) ObjKit.toRealValue(e.getKey(), keyType);
                V value = (V) ObjKit.toRealValue(e.getValue(), valueType);
                result.put(key, value);
            }
            return result;
        }
        for (Object o : source.entrySet()) {
            Map.Entry e = (Map.Entry) o;
            Map.Entry fe = force.force(e.getKey(), e.getValue());
            if(fe == null) continue;
            K key = (K) ObjKit.toRealValue(fe.getKey(), keyType);
            V value = (V) ObjKit.toRealValue(fe.getValue(), valueType);
            result.put(key, value);
        }
        return result;
    }

    @Note("将 source 里的数据拷贝到 result 里，拷贝过程中会对 key、value 做指定的类型转换")
    private static <K, V> Map<K, V> private_asMap(Map<K, V> result, OwnPairs source, C<K> keyType, C<V> valueType, ForcePair force) {
        if(force == null) {
            for (Object o : source.entrySet()) {
                Map.Entry e = (Map.Entry) o;
                V value = (V) ObjKit.toRealValue(e.getValue(), valueType);
                K key = (K) ObjKit.toRealValue(e.getKey(), keyType);
                result.put(key, value);
            }
        }
        else {
            for (Object o : source.entrySet()) {
                Map.Entry e = (Map.Entry) o;
                Map.Entry fe = force.force(e.getKey(), e.getValue());
                if(fe == null) continue;
                V value = (V) ObjKit.toRealValue(fe.getValue(), valueType);
                K key = (K) ObjKit.toRealValue(fe.getKey(), keyType);
                result.put(key, value);
            }
        }
        return result;
    }


    @Note("将 source 里的数据拷贝到 result 里，拷贝过程中会将 key、value 转为字符串")
    private static Map<String, String> private_propertiesAsMap(Map<String, String> result, Properties source, ForcePair<String, String> force) {
        if(force == null) {
            for (Object o : source.entrySet()) {
                Map.Entry e = (Map.Entry) o;
                result.put(e.getKey().toString(), e.getValue().toString());
            }
            return result;
        }
        for (Object o : source.entrySet()) {
            Map.Entry e = (Map.Entry) o;
            e = force.force(e.getKey().toString(), e.getValue().toString());
            if(e == null) continue;
            result.put(ObjKit.asStringValue(e.getKey(), null), ObjKit.asStringValue(e.getValue(), null));
        }
        return result;
    }

    @Note("将 source 里的数据拷贝到 result 里，拷贝过程中会将 key、value 转为字符串和 Object。" +
            "注意，Properties 如果有 JSON 字符串不会自动反序列化为对象")
    private static Map<String, Object> private_propertiesAsMap2(Map<String, Object> result, Properties source, ForcePair<String, String> force) {
        if(force == null) {
            for (Object o : source.entrySet()) {
                Map.Entry e = (Map.Entry) o;
                result.put(e.getKey().toString(), ObjKit.stringToRealValue(e.getValue().toString(), true));
            }
        }
        else {
            for (Object o : source.entrySet()) {
                Map.Entry e = (Map.Entry) o;
                e = force.force(e.getKey().toString(), e.getValue().toString());
                if(e == null) continue;
                result.put(ObjKit.asStringValue(e.getKey(), null), ObjKit.stringToRealValue(ObjKit.asStringValue(e.getValue(), null), true));
            }
        }
        return result;
    }


    @Note("将 source 的内容拷贝到 result，拷贝过程中会对 Map.Entry 做一些自定义增强逻辑")
    private static <K, V> Map<K, V> private_asMap(Map<K, V> result, Map<? extends K, ? extends V> source, ForcePair<K, V> force) {
        if(force == null) {
            result.putAll(source);
            return result;
        }
        for (Map.Entry<? extends K, ? extends V> e : source.entrySet()) {
            Map.Entry<K, V> fe = force.force(e.getKey(), e.getValue());
            if(fe == null) continue;
            result.put(fe.getKey(), fe.getValue());
        }
        return result;
    }


    @Note("将 source 的内容拷贝到 result，拷贝过程中会对 Map.Entry 做一些自定义增强逻辑")
    private static <K, V> Map<K, V> private_asMap(Map<K, V> result, OwnPairs<? extends K, ? extends V> source, ForcePair<K, V> force) {
        if(force == null) {
            for (Map.Entry<? extends K, ? extends V> e : source.entrySet()) {
                result.put(e.getKey(), e.getValue());
            }
            return result;
        }
        for (Map.Entry<? extends K, ? extends V> e : source.entrySet()) {
            Map.Entry<K, V> fe = force.force(e.getKey(), e.getValue());
            if(fe != null) result.put(fe.getKey(), fe.getValue());
        }
        return result;
    }
}
